/*
 	A set of qunit helper methods
 */



var stub = function(orig, func){
 
 // store the original
 func.orig = orig;
 
 // return the new function
 return func;
 
};
var unstub = function(func) {
 return func.orig;
};


/*
	LOGGING
 */
function debug() {
	
	if (window.console) {
		console.info.apply(window.console, arguments);
	} else {
		alert(arguments[0]);
	}
	
};


/*
 	EXCEPTIONS
 */

// excepts([message ,] function);
function excepts() {
	var func, m;
	if (arguments.length == 1) {
		func = arguments[0];
	} else {
		m = arguments[0];
		func = arguments[1];
	}
	
	m = m || "An exception should be thrown.";
	var failed = false;
	try {
		func.call();
	} catch (e) {
		failed = true;
	}
	ok(failed, m);
};

//notExcepts([message ,] function);
function notExcepts() {
	var func, m;
	if (arguments.length == 1) {
		func = arguments[0];
	} else {
		m = arguments[0];
		func = arguments[1];
	}
	
	m = m || "An exception should not be thrown.";
	var failed = false;
	try {
		func.call();
	} catch (e) {
		failed = true;
	}
	ok(!failed, m);
};

/*
	TYPE MATCHING
 */
function something(o, m) {
	m = m || "Item should not be null or undefined.";
	ok(typeof o != "undefined", m + " (checked for undefined)");
	ok(o != null, m + " (checked for null)");
};
function isFunction(o, m) {
	isType(o, "function", m);
};
function isString(o, m) {
	isType(o, "string", m);
};
function isObject(o, m) {
	isType(o, "object", m);
};
function isNumber(o, m) {
	isType(o, "number", m);
};
function isArray(o, m) {
	
	// must be an object
	isObject(o, m);
	
	// must have a length
	ok(typeof o.length != "undefined", "Arrays should be objects with a length property.");
	isNumber(o.length, m);
	
};
function isType(o, t, m) {

	var actual = typeof o;
	m = m || "Expected type '" + t + "' - Actual type '" + actual + "'.";
	equals(actual, t, m);
	
};


/*
	objx specific helpers
*/

function provided(n) {

	notExcepts("'" + n + "' should have been provided with: OProvides(\"" + n + "\");", function(){
		objx("<< test code >>").requires(n);
	});

}